package com.biostime.qdingding.modules.qd.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.biostime.qdingding.common.service.CrudService;
import com.biostime.qdingding.common.utils.DateUtils;
import com.biostime.qdingding.common.utils.StringUtils;
import com.biostime.qdingding.modules.qd.api.dto.CourseCalendarParamDto;
import com.biostime.qdingding.modules.qd.api.dto.CourseDetailDto;
import com.biostime.qdingding.modules.qd.api.dto.CourseDto;
import com.biostime.qdingding.modules.qd.api.dto.CourseOrderDto;
import com.biostime.qdingding.modules.qd.api.dto.CoursesOrderingDto;
import com.biostime.qdingding.modules.qd.api.dto.MyCourseDto;
import com.biostime.qdingding.modules.qd.api.dto.ParentGuidanceDto;
import com.biostime.qdingding.modules.qd.dao.CourseDao;
import com.biostime.qdingding.modules.qd.dao.CourseOrderDao;
import com.biostime.qdingding.modules.qd.entity.Center;
import com.biostime.qdingding.modules.qd.entity.Contract;
import com.biostime.qdingding.modules.qd.entity.Course;
import com.biostime.qdingding.modules.qd.entity.CourseOrder;
import com.biostime.qdingding.modules.qd.entity.Privilege;
import com.biostime.qdingding.modules.qd.entity.Privrecord;
import com.biostime.qdingding.modules.qd.entity.Student;
import com.biostime.qdingding.modules.qd.entity.Transrecord;
import com.biostime.qdingding.modules.qd.push.MsgTemplate;
import com.biostime.qdingding.modules.qd.push.MsgTemplate.Abort;
import com.biostime.qdingding.modules.qd.utils.CalendarUtils;
import com.biostime.qdingding.modules.qd.utils.CalendarUtils.WeekInfo;
import com.biostime.qdingding.modules.sys.entity.User;
import com.google.common.collect.Lists;

/**
 * 排课表Service
 * @author phil
 * @version 2015-11-11
 */
@Service
public class CourseService extends CrudService<CourseDao,Course>{ 
	
	@Autowired
	private CourseDao courseDao;
	@Autowired
	private TipsMessageService tipsMessageService;
	@Autowired
	private MessageService messageService;	
	@Autowired
	private CourseOrderService courseOrderService;
	@Autowired
	private CourseOrderDao courseOrderDao;
	@Autowired
	private StudentService studentService;
	@Autowired
	private TransrecordService transrecordService;
	@Autowired 
	private PrivilegeService privilegeService;
	@Autowired
	private PrivrecordService privrecordService;
	@Autowired
	private CouponService couponService;
	
	@Override
	public List<Course> findList(Course entity) {
		dataScopeFilter(entity, "dsf", "id=a.center_id", "id=a.create_by");
		
		return super.findList(entity);
	}

	public List<Course> findListByWeek(Course course, Date start, Date end) {
		dataScopeFilter(course, "dsf", "id=a.center_id", "id=a.create_by");
		
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(start);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		
		start = calendar.getTime();
		
		calendar.setTime(end);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 0);
		
		end = calendar.getTime();
		
		return dao.findListByWeek(course,start,end);
	}
	
	@Transactional
	public List<HashMap<String, Object>> order(HttpServletRequest request) {
		String courseId = request.getParameter("courseId");
		String couponId = request.getParameter("couponId");
		Course course = get(courseId);
		
		String orderStudents = request.getParameter("orderStudents");
		
		if(StringUtils.isEmpty(orderStudents)){
			return null;
		}
		
		List<HashMap<String, Object>> info = Lists.newArrayList();
		
		String[] students = orderStudents.split(",");
		for(String s : students){
			String[] student = s.split("\\|");
			if(student.length==2){
				try {
					Student stu = studentService.get(student[0]);
					
					HashMap<String, Object> res = courseOrderService.apiOrderCourse(course, student[1], stu.getMember().getId(), student[0], String.valueOf(course.getType()),couponId);
					res.put("studentName", stu.getName());
					info.add(res);
					
					logger.info(res.toString());
				} catch (Exception e) {
					logger.error("课程预约["+student[0]+student[1]+courseId+"]异常", e);
					e.printStackTrace();
				}
			}
		}
		return info;
	}	

	@Transactional
	public HashMap<String,Object> cancelOrder(HttpServletRequest request) {
		return courseOrderService.cancelOrder(request);
	}
	
	@Transactional
	public HashMap<String,Object> leaveCourse(HttpServletRequest request) {
		return courseOrderService.leaveCourse(request,"background");
	}

	@Transactional
	public String abortOrder(HttpServletRequest request) {
		return courseOrderService.abortOrder(request);
	}

	/**如果一节课已经有人预约了，课程的信息不能修改，除了：教室、老师、主题介绍、课程图片**/
	public boolean getCourseReadonly(Course course) {
		return dao.getCourseReadonly(course);
	}

	public List<HashMap<String, Object>> getCourseStudents(Integer type,
			Integer courseId) {
		return dao.getCourseStudents(type, courseId);
	}

	public List<HashMap<String, Object>> getAbortStudents(Integer type,
			Integer integer) {
		return dao.getAbortStudents(type, integer);
	}

	public void stopCourse(Course course) {
		List<HashMap<String,Object>> orderedStudents = dao.getAbortStudents(course.getType(),StringUtils.toInteger(course.getId()));
		for(HashMap<String,Object> orderedStudent : orderedStudents){
			int memberId = StringUtils.toInteger(orderedStudent.get("memberId"));//会员编号
			int studentId = StringUtils.toInteger(orderedStudent.get("studentId")); //学员编号
			int orderId = StringUtils.toInteger(orderedStudent.get("id"));//订单编号
			int contractId = StringUtils.toInteger(orderedStudent.get("contractId"));//合同编号
			int centerId = StringUtils.toInteger(orderedStudent.get("centerId"));//早教中心编号
			
			double money = StringUtils.toDouble(orderedStudent.get("money"));
			int leaveCount = StringUtils.toInteger(orderedStudent.get("leaveCount"));
			int abortCount = StringUtils.toInteger(orderedStudent.get("abortCount"));
			
			/**扣费返款**/
			if(money>0){
				SimpleDateFormat df = new SimpleDateFormat("MM月dd日");
				Date now = new Date();
				
				Transrecord tr = new Transrecord();
				tr.setInout(0);// 收支类型，0收，1支 (以会员的角度)
				
				//0	充值	trans_type	交易类型
				//1	请假特权	trans_type	交易类型
				//2	取消特权	trans_type	交易类型
				//3	普通课程	trans_type	交易类型
				//4	户外课程	trans_type	交易类型
				//5	课程取消返款	trans_type	交易类型
				tr.setType("5");//交易类型
				tr.setMoney(money); // 交易金额
				
				//0	POS机刷卡	trans_way	交易方式
				//1	微信支付	trans_way	交易方式
				//2	支付宝支付	trans_way	交易方式
				//3	银联在线支付	trans_way	交易方式
				//4	系统返还	trans_way	交易方式
				//5	系统扣费	trans_way	交易方式
				//6	现金支付	trans_way	交易方式
				tr.setPayType("4"); //支付方式
				//tr.setPayCode("－"); //支付单号
				tr.setPayDate(new Date()); //发生日期
				tr.setDescription(String.format("[%s %s%s]课程取消，系统返还",df.format(course.getOndate()), course.getClevel(), course.getSerial(), tr.getMoney())); //描述
				tr.setMemberId(memberId); //会员编号
				tr.setStudentId(studentId); //学员编号
				tr.setCourseorderId(orderId); //预约课程编号
				tr.setContractId(contractId); //合同编号
				tr.setInvalid(0); //是否作废
				tr.setCenterId(centerId);//早教中心
				tr.setCreateBy(new User("0"));
				tr.setCreateDate(now);
				tr.setUpdateBy(new User("0"));
				tr.setUpdateDate(now);
				transrecordService.save(tr);
			}
			
			/**特权恢复**/
			if(leaveCount>0){
				Privilege p = privilegeService.apiGetPrivilege("leave", String.valueOf(contractId));	
				if(p != null){
					Privrecord record = new Privrecord();
					record.setCenter(new Center(String.valueOf(centerId)));
					record.setPrivilege(p);
					record.setContract(new Contract(String.valueOf(contractId)));
					record.setCreateBy(new User("0"));
					record.setCount(-leaveCount);
					record.setCourseorderId(orderId);
					privrecordService.save(record);
					
					p.setUsed(p.getUsed()-leaveCount);
					privilegeService.save(p);
				}
			}
			
			if(abortCount>0){
				Privilege p = privilegeService.apiGetPrivilege("abort", String.valueOf(contractId));	
				if(p != null){
					Privrecord record = new Privrecord();
					record.setCenter(new Center(String.valueOf(centerId)));
					record.setPrivilege(p);
					record.setContract(new Contract(String.valueOf(contractId)));
					record.setCreateBy(new User("0"));
					record.setCount(-abortCount);
					record.setCourseorderId(orderId);
					privrecordService.save(record);
					
					p.setUsed(p.getUsed()-abortCount);
					privilegeService.save(p);
				}
			}
			/**订单状态**/
			CourseOrder courseOrder = courseOrderService.get(String.valueOf(orderId));
			if(courseOrder!=null){
				courseOrder.setState("canceled");
				
				//修改优惠券使用记录，标记为未使用
				if(courseOrder.getCouponId() == null){
					courseOrder.setCouponId(0); 
				}
				couponService.useCoupon(String.valueOf(courseOrder.getCouponId()) ,"0"); 
				
				courseOrderService.save(courseOrder);
			}
			
			/**发送停课通知**/
			SimpleDateFormat df = new SimpleDateFormat("MM月dd日");
			String message = "";
			if(money>0){
				message = Abort.content;
			}else{
				message = Abort.content_;
			}
			message = message.replace(MsgTemplate.money, String.format("%.2f", money));
			message = message.replace(MsgTemplate.date, df.format(course.getOndate()));
			message = message.replace(MsgTemplate.section, course.getSection());
			message = message.replace(MsgTemplate.level, course.getClevel());
			message = message.replace(MsgTemplate.serial, course.getSerial());
			message = message.replace(MsgTemplate.theme, course.getTheme());
			
			String pushMsg = "";
			if(money>0){
				pushMsg = Abort.push;
			}else{
				pushMsg = Abort.push_;
			}
			pushMsg = pushMsg.replace(MsgTemplate.money, String.format("%.2f", money));
			pushMsg = pushMsg.replace(MsgTemplate.date, df.format(course.getOndate()));
			pushMsg = pushMsg.replace(MsgTemplate.section, course.getSection());
			pushMsg = pushMsg.replace(MsgTemplate.level, course.getClevel());
			pushMsg = pushMsg.replace(MsgTemplate.serial, course.getSerial());
			pushMsg = pushMsg.replace(MsgTemplate.theme, course.getTheme());
			
			messageService.sendAndPush(Abort.category, String.valueOf(studentId), Abort.title, message, String.valueOf(memberId), pushMsg);
		}
		
		/**删除课程**/
		dao.delete(course);
	}
	
	//<!-- ————————————————————————————楚河汉界，谁敢动我的，打死! ————————————————————————————————————-->
	public CourseDetailDto apiGetCourseDetail(String courseId,String studentId ,String type){
		return courseDao.apiGetCourseDetail(courseId,studentId,type);
	}
	
	public List<Course> apiFindList(String centerId,String orderType){
		return courseDao.apiFindList(centerId,orderType);
	}
	
	/**
	 * 按时间分组
	 */
	@SuppressWarnings("unchecked")
	public List<CoursesOrderingDto> apiFindCourseOrderDto(HashMap<String,Object> map){	
		
		String centerId = (String) map.get("centerId");
		String studentId = (String) map.get("studentId");
		String orderType = (String) map.get("orderType");
		//String type = (String) map.get("type");
		List<String> serialIds = (List<String>) map.get("serialIds");
		List<String> levelIds = (List<String>) map.get("levelIds");
		List<String> coursedays = (List<String>) map.get("coursedays");	
		List<CoursesOrderingDto>  list = courseDao.apiFindCourseOrderDto(centerId, orderType, studentId ,serialIds,
				levelIds,coursedays,null);
				
		return list;
	}
	
	/**
	 * 不按时间分组
	 */
	@SuppressWarnings("unchecked")
	public List<CoursesOrderingDto> apiFindCourseOrderDto2(HashMap<String,Object> map){	
		
		String centerId = (String) map.get("centerId");
		String studentId = (String) map.get("studentId");
		String orderType = (String) map.get("orderType");
		String type = (String) map.get("type");
		List<String> serialIds = (List<String>) map.get("serialIds");
		List<String> levelIds = (List<String>) map.get("levelIds");
		List<String> coursedays = (List<String>) map.get("coursedays");	
		List<CourseOrderDto>  courseList = courseDao.apiFindCourseOrderDto2(centerId, orderType, studentId ,serialIds,
				levelIds,coursedays,type);
		
		//Date转字符串
		List<CoursesOrderingDto> list = new ArrayList<CoursesOrderingDto>();
		SimpleDateFormat sdf =   new SimpleDateFormat( "yyyy-MM-dd" );
		
		for(CourseOrderDto orderList : courseList){

			List<CourseOrderDto>  course2List = new ArrayList<CourseOrderDto>();
			course2List.add(orderList);
			
			CoursesOrderingDto  orderDto = new CoursesOrderingDto();
			orderDto.setCourseOrders(course2List);
			orderDto.setDay(course2List.get(0).getDay());
			String str = sdf.format(course2List.get(0).getOndate());
			orderDto.setDate(str);
			
			list.add(orderDto);
					
		}
				
		return list;
	}	
	
	/**
	 * 此方法用于将课程列表通过价格大小排序
	 * @return
	 */
	public List<CoursesOrderingDto> getCourseByPrice(List<CoursesOrderingDto> list,String orderType){
			
		//新集合，用于迭代新的课程
		List<CoursesOrderingDto>  courseList = new ArrayList<CoursesOrderingDto>();
		
		if(list != null && !list.isEmpty()){
						
			//用于价格的数组
		    double a[]=new double[list.size()];	
		    
		    //用于id的数组
		    int b[]=new int[list.size()];
		    
			for(int l=0;l<list.size();l++){			    			
				double money = list.get(l).getCourseOrders().get(0).getMoneyAfter(); 
				a[l] = money;
				b[l] = l;		
			}
			
			//冒泡排序
		    double temp=0;  
		    int order = 0;
		    for(int i=0;i<a.length-1;i++){  
		         for(int j=0;j<a.length-1-i;j++){  
		         if(a[j]>a[j+1]){  
		        	 
		             temp=a[j];  
		             order=b[j];
		             
		             a[j]=a[j+1];  
		             b[j]=b[j+1];
		             
		             a[j+1]=temp; 
		             b[j+1]=order;
		         }  
		         }  
		    }  
							
			//判断是升序还是降序
			if(orderType.equals("priceup")){
				for(int i=0;i<b.length;i++){
					courseList.add(list.get(b[i]));
				}						
			}else{
				
				for(int i=(b.length - 1);i>=0;i--){
					courseList.add(list.get(b[i]));
				}						
			}	
														
		}
		
		return courseList;
		
	}	
	
	
	public List<Map<String,Object>> apiCourseCalendar(CourseCalendarParamDto cd){
		if(cd.getWeekFrom()!=null && !cd.getWeekFrom().equals("")){
			String[] week=cd.getWeekFrom().split("/");
			WeekInfo wi=CalendarUtils.getWeek(Integer.parseInt(week[0]),Integer.parseInt(week[1]));
			cd.setWeekFrom(DateUtils.formatDate(wi.getCells().get(0).getDate(), "yyyy-MM-dd"));
			List<MyCourseDto> list=dao.apiCourseCalendar(cd);
			
			for(MyCourseDto dto : list){
				if(dto.getState() != null && dto.getState().equals("canceled")){
					dto.setState("null"); 
				}
			}
			
			return courseOrderService.apiParseWeekList(list,true,cd.getStudentId());
		}else{
			List<MyCourseDto> list=dao.apiCourseCalendar(cd);
			return courseOrderService.apiParseMonthList(list,true,cd.getStudentId());
		}
	};
	
	public Course apiGetInOrOut(String type,String courseId){
		return courseDao.apiGetInOrOut(type, courseId);
	}
	
	public List<CoursesOrderingDto> apiGetHotCourse(String studentId,String centerId){
		HashMap<String,Object> hashMap = studentService.apiGetLevel(studentId, centerId);
		int levelId = 0;
		if(hashMap != null){
			levelId = (int) hashMap.get("id");
		}
		return courseDao.apiGetHotCourse(String.valueOf(levelId),centerId,studentId); 
	}
	
	public List<CourseDto> apiMyRecentCourse(String studentId){
		return courseDao.apiMyRecentCourse(studentId);
	}
	
	@Transactional
	public int apiChangeOrder(String id, String state ,String type,String courseId ,String studentId,String userId) {
		Course course = courseDao.apiGetInOrOut(type, courseId);			
		
		//新增消息
		int messageId = messageService.apiInsertMessage("leaved",studentId,tipsMessageService.tips(course,0d, "leaved"));
		
		//推送消息
		HashMap<String,Object> hashMap = new HashMap<String,Object>();
		hashMap.put("title", "请假通知");
		hashMap.put("content", tipsMessageService.tips(course, 0d,"leaved"));
		hashMap.put("category", "leaved");
		hashMap.put("userId", userId);
		hashMap.put("id", String.valueOf(messageId));
		courseOrderService.sendMessage(hashMap);					
			
		return courseOrderDao.apiChangeOrder(id, state);
	}
	
	public List<ParentGuidanceDto> apiGetGuidenceList(String studentId){
		return dao.apiGetGuidenceList(studentId);
	}

}


